11.構造体

11-9. データチェイン

◇データチェインとは?

さて、いきなりデータチェインと出てきて「これは何だ?」と思いました?これはデータとデータを鎖(チェーン)上につないだ状態のものを指します。

たとえば、数のように構造体データを並べます。

 ┌─┐  ┌─┐  ┌─┐  ┌─┐  ┌─┐
 │A│─→│B│─→│C│─→│D│─→│E│
 └─┘  └─┘  └─┘  └─┘  └─┘

最初からこの並びで以後変更する必要が無いのなら配列でも構いません。

データチェインはこれを、

 ┌─┐  ┌─┐  ┌─┐  ┌─┐  ┌─┐
 │B│─→│E│─→│D│─→│A│─→│C│
 └─┘  └─┘  └─┘  └─┘  └─┘

と変更したり、することができます。
データチェインも(一種のデータ構造です)

プログラミング例:

#include<stdio.h>

typedef struct data_chain{
	int	number;
	char *p_string;
	struct data_chain *p_st;
}DataChain;

main()
{
	DataChain s1={1,"NameA",NULL};
	DataChain s2={2,"NameB",NULL};
	DataChain s3={3,"NameC",NULL};
	DataChain s4={4,"NameD",NULL};
	DataChain s5={5,"NameE",NULL};
	DataChain *p_data;
	
	s1.p_st = &s2;
	s2.p_st = &s3;
	s3.p_st = &s4;
	s4.p_st = &s5;
	
	for(p_data = &s1; p_data != NULL; p_data = p_data->p_st)
		printf("%2d %s\n",p_data->number, p_data->p_string);
		return;
}

結果:
1 NameA
2 NameB
3 NameC
4 NameD
5 NameE

解説は次回、一つ一つトレースしながらやってみます。
それまでの一週間上記のプログラムの原理を解析して見てください。

◇データチェインの解析

以下のプログラムをトレースしながら解析して見ましょう。

プログラミング例:

 1: #include<stdio.h>
 2: 
 3: typedef struct data_chain{
 4:     int     number;
 5:     char *p_string;
 6:     struct data_chain *p_st;
 7: }DataChain;
 8: 
 9: main()
10: {
11:     DataChain s1={1,"NameA",NULL};
12:     DataChain s2={2,"NameB",NULL};
13:     DataChain s3={3,"NameC",NULL};
14:     DataChain s4={4,"NameD",NULL};
15:     DataChain s5={5,"NameE",NULL};
16:     DataChain *p_data;
17: 
18:     s1.p_st = &s2;
19:     s2.p_st = &s3;
20:     s3.p_st = &s4;
21:     s4.p_st = &s5;
22: 
23:     for(p_data = &s1; p_data != NULL; p_data = p_data->p_st)
24:             printf("%2d %s\n",p_data->number, p_data->p_string);
25:             return;
26: }

プログラム解説:
3- 7: 構造体DataChain型の定義
11-15: 各構造体s1,s2,s3,s4,s5の定義
16: カレント構造体(変な言い方^^;)のためのポインタ
18-21: s1からs4まで次に移動する構造体のアドレスを構造体内の
ポインタに定義
23: ポインタ初期値はs1、そしてポイント先がNULLになるまで繰返し
そしてループしたとき、その構造体内のポインタ値をp_dataに代入
(つまり、カレント構造体を次の構造体に変える)
24: そしてカレント構造体の中身を表示

23-24の部分を具体的にトレースしてみます。

1.まず、それぞれの構造体とポインタの初期化・代入が終わったところです。

p_data s1 s2 s3 s4 s5
+—–+ +—–+ +—–+ +—–+ +—–+ +—–+
| &s1 |–>| 1 | +->| 2 | +->| 3 | +->| 4 | +->| 5 |
+—–+ +—–+-+ | +—–+-+ | +—–+-+ | +—–+-+ | +—–+-+
| NameA | | | NameB | | | NameC | | | NameD | | | NameE |
+—–+-+ | +—–+-+ | +—–+-+ | +—–+-+ | +—–+-+
| &s2 |—+ | &s3 |—+ | &s4 |—+ | &s5 |—+ | |
+—–+ +—–+ +—–+ +—–+ +—–+

この時点でチェーン構造はできあがりました。
カレント構造体(p_dataが指す構造体)を表示します。(ここではs1)

1 NameA

と表示されます。

次に、s1.p_stの値をp_dataにコピーします。この時点で図は

p_data s2 s3 s4 s5
+—–+ +—–+ +—–+ +—–+ +—–+
| &s2 |–>| 2 | +->| 3 | +->| 4 | +->| 5 |
+—–+ +—–+-+ | +—–+-+ | +—–+-+ | +—–+-+
| NameB | | | NameC | | | NameD | | | NameE |
+—–+-+ | +—–+-+ | +—–+-+ | +—–+-+
| &s3 |—+ | &s4 |—+ | &s5 |—+ | |
+—–+ +—–+ +—–+ +—–+

このようになります。ここで表示を行えば、

2 NameB

と出ます。これを繰り返していくと

p_data s
+—–+ +—–+
| &s5 |–>| 5 |
+—–+ +—–+-+
| NameE |
+—–+-+
| |
+—–+

となります。s5.p_stはNULLであり、これがp_dataにコピーされ、
p_dataがNULLになればforから脱出して処理は終了します。